﻿namespace ScrumLite.WebUx.Tests
{
    using System;
    using System.Configuration;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using ScrumLite.Services;
    using ScrumLite.Services.Contracts;
    using ScrumLite.WebUx.Controllers;
    using ScrumLite.WebUx.Models;
    using System.Globalization;
    using System.Web.Mvc;


    /// <summary>
    /// Summary description for ReviewsControllerFixture
    /// </summary>
    [TestClass]
    public class ReviewsControllerFixture
    {
        [TestMethod]
        public void ShouldAddNewReviewOnSaveWithEmptyReviewId()
        {
            MockReviewsService reviewService = new MockReviewsService();
            MockReviewsService.InitializeData();
            TestableReviewsController controller = new TestableReviewsController(reviewService);
            MockHelpers.SetupMocks(controller);

            controller.Save("AF06A611-12CE-4C06-B3AD-E2754D12D516", String.Empty, DateTime.Now, "southy", "some url");

            Assert.IsTrue(reviewService.AddReviewCalled);
            Assert.AreEqual(new Guid("AF06A611-12CE-4C06-B3AD-E2754D12D516"), reviewService.ReviewAdded.ProjectId);
            Assert.AreEqual(DateTime.Now.Date, reviewService.ReviewAdded.OccurredOn.Date);
        }

        [TestMethod]
        public void ShouldUpdateReviewOnSaveWithNotEmptyReviewId()
        {
            MockReviewsService reviewService = new MockReviewsService();
            MockReviewsService.InitializeData();
            TestableReviewsController controller = new TestableReviewsController(reviewService);
            MockHelpers.SetupMocks(controller);

            Review[] reviews = reviewService.GetReviews("AF06A611-12CE-4C06-B3AD-E2754D12D516");

            controller.Save("AF06A611-12CE-4C06-B3AD-E2754D12D516", reviews[0].Id.ToString(), reviews[0].OccurredOn, reviews[0].ConductedBy, "evidence url updated");

            Assert.IsTrue(reviewService.UpdateReviewCalled);
            Assert.AreEqual("evidence url updated", reviewService.ReviewUpdated.EvidenceUrl);
        }

        [TestMethod]
        public void ShouldControllerPassDefaultReviewValuesToViewNew()
        {
            MockReviewsService reviewService = new MockReviewsService();
            MockReviewsService.InitializeData();
            MockProjectsService projectService = new MockProjectsService();          
            TestableReviewsController controller = new TestableReviewsController(reviewService);
            MockHelpers.SetupMocks(controller);

            controller.New("AF06A611-12CE-4C06-B3AD-E2754D12D516");

            Assert.IsNotNull(controller.DataToShow);
            Assert.IsInstanceOfType(controller.DataToShow, typeof(ReviewsWriteViewData));
            Assert.AreEqual(DateTime.Now.Date, ((ReviewsWriteViewData)controller.DataToShow).Review.OccurredOn.Date);
            Assert.AreEqual(string.Format(CultureInfo.InvariantCulture,"{0}/{1}", projectService.GetProjectRepository("AF06A611-12CE-4C06-B3AD-E2754D12D516"), ConfigurationManager.AppSettings["defaultReviewPath"]), ((ReviewsWriteViewData)controller.DataToShow).Review.EvidenceUrl);
        }

        [TestMethod]
        public void ShouldControllerPassReviewsToViewList()
        {
            MockReviewsService reviewService = new MockReviewsService();
            MockReviewsService.InitializeData();
            TestableReviewsController controller = new TestableReviewsController(reviewService);
            MockHelpers.SetupMocks(controller);

            controller.List("AF06A611-12CE-4C06-B3AD-E2754D12D516");

            Assert.IsNotNull(controller.DataToShow);
            Assert.IsInstanceOfType(controller.DataToShow, typeof(ReviewListViewData));
            Assert.IsTrue(((ReviewListViewData)controller.DataToShow).Reviews.Count > 0);
        }
        [TestMethod]
        public void ShouldRenderReviewsMetricsWithData()
        {
            string mockProjectUri = "AF06A611-12CE-4C06-B3AD-E2754D12D516";
            MockReviewsService service = new MockReviewsService();
            MockReviewsService.InitializeData();
            TestableReviewsController controller = new TestableReviewsController(service);

            controller.ReviewsMetrics(mockProjectUri);

            Assert.AreEqual("ReviewsMetrics", controller.ViewToShow);
            Assert.IsInstanceOfType(controller.DataToShow, typeof(ReviewsMetricsData));
            Assert.IsInstanceOfType(controller.DataToShow, typeof(ContextViewData));
        }

        [TestMethod]
        public void ShouldCallGetReviewsOnRenderMetricsView()
        {
            string mockProjectUri = "AF06A611-12CE-4C06-B3AD-E2754D12D516";
            MockReviewsService requestsService = new MockReviewsService();
            MockReviewsService.InitializeData();
            requestsService.GetReviewsByWeekCalled = false;
            TestableReviewsController controller = new TestableReviewsController(requestsService);

            controller.ReviewsMetrics(mockProjectUri);

            Assert.IsTrue(requestsService.GetReviewsByWeekCalled);
            Assert.IsNotNull(((ReviewsMetricsData)controller.DataToShow).WeeklyRequests);
            Assert.AreEqual(2, ((ReviewsMetricsData)controller.DataToShow).WeeklyRequests.Count);
        }

        [TestMethod]
        public void ShouldGenerateReviewsMetricsLineUrl()
        {
            string mockProjectUri = "AF06A611-12CE-4C06-B3AD-E2754D12D516";
            MockReviewsService requestsService = new MockReviewsService();
            MockReviewsService.InitializeData();
            TestableReviewsController controller = new TestableReviewsController(requestsService);

            controller.ReviewsMetrics(mockProjectUri);

            string expectedUrl = @"http://chart.apis.google.com/chart?cht=lc&chs=500x250&chd=t:10.0,20.0|15.0,15.0&chtt=Weekly+reviews&chco=ff0000,0000ff&chdl=Reviews|Average&chxt=x,y&chxl=0:|W4|W5|1:&chxr=1,0,10&chls=3,1,0|1,6,3";
            Assert.AreEqual(expectedUrl, ((ReviewsMetricsData)controller.DataToShow).GChartReviewsLine);
        }

        [TestMethod]
        public void ShouldGenerateEmptyReviewsMetricsLineUrl()
        {
            string mockProjectUri = MockReviewsService.ProjectIdForEmptyData;
            MockReviewsService reviewsService = new MockReviewsService();
            TestableReviewsController controller = new TestableReviewsController(reviewsService);

            controller.ReviewsMetrics(mockProjectUri);

            string expectedUrl = String.Format(CultureInfo.InvariantCulture,"/{0}/{1}", ConfigurationManager.AppSettings["SiteImagesPath"], "chart_EmptyWeeklyReviewsLine.png");
            Assert.AreEqual(expectedUrl, ((ReviewsMetricsData)controller.DataToShow).GChartReviewsLine);
        }
    }

    class TestableReviewsController : ReviewsController
    {
        public object DataToShow { get; set; }
        public object ViewToShow { get; set; }

        public TestableReviewsController()
            : this(new MockReviewsService(), new MockProjectsService(), new MockProfileService())
        { }

        public TestableReviewsController(IReviewsService reviewService)
            : this(reviewService, new MockProjectsService(), new MockProfileService())
        { }
        public TestableReviewsController(IReviewsService reviewService, IProjectsService projectService, IProfileService profileService)
            : base(reviewService, projectService, profileService)
        { }

        protected override void RedirectToAction(object values)
        {
        }

        protected override void RenderView(string viewName, string masterName, object viewData)
        {
            ViewToShow = viewName;
            DataToShow = viewData;
        }
    }
}
